package com.printeverywhere.action;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Restrictions;

import com.opensymphony.xwork2.ActionContext;
import com.printeverywhere.delegator.AuctionBidsServiceDelegator;
import com.printeverywhere.delegator.CommonFunctionDelegator;
import com.printeverywhere.delegator.ItemsServiceDelegator;
import com.printeverywhere.delegator.ItemsWatchListServiceDelegator;
import com.printeverywhere.delegator.UserServiceDelegator;
import com.printeverywhere.dto.AuctionBids;
import com.printeverywhere.dto.BidStatus;
import com.printeverywhere.dto.ItemNote;
import com.printeverywhere.dto.ItemWantedBestOffer;
import com.printeverywhere.dto.Items;
import com.printeverywhere.dto.ItemsWatchlist;
import com.printeverywhere.dto.Itemtype;
import com.printeverywhere.dto.ListingOptions;
import com.printeverywhere.dto.MyAccountCount;
import com.printeverywhere.dto.User;
import com.printeverywhere.dto.UserRating;
import com.printeverywhere.util.AdminConstants;
import com.printeverywhere.util.AttributeConstants;
import com.printeverywhere.util.DateUtil;
import com.printeverywhere.util.SearchCriteria;
import com.printeverywhere.util.SearchListCriteria;
import com.printeverywhere.util.SessionUtil;
import com.printeverywhere.util.Sort;

public class SellingAction extends FrontBaseSupport implements ServletRequestAware{

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	private static Logger logger = Logger.getLogger(SellAction.class);

	private List<Items> itemsList = new ArrayList<Items>();

	private List<ItemsWatchlist> itemsWatchList = new ArrayList<ItemsWatchlist>();

	private List<AuctionBids> auctionBidsList = new ArrayList<AuctionBids>();

	private List<Items> itemsListTemp = new ArrayList<Items>();

	private SearchListCriteria searchListCriteria = new SearchListCriteria();

	private SearchCriteria searchCriteria = new SearchCriteria();

	private User user;

	private HttpServletRequest request;

	private ListingOptions listingOptions;

	private Date date;

	private Items item;

	private String action;

	private String type;

	private MyAccountCount myAccountCount = new MyAccountCount();

	public SellingAction() {
		super(true, false);
		setMyAccount(true);
	}

	@Override
	public String execute() throws Exception{
		try {
			getSellingAuctionData();
			if(request.getParameter("sort") != null && request.getParameter("sort").equalsIgnoreCase("title")){
				itemsList = Sort.byItemTitle(itemsList);
			}
			if(request.getParameter("sort") != null && request.getParameter("sort").equalsIgnoreCase("price")){
				itemsList = Sort.byItemBuyPrice(itemsList);
			}
			if(request.getParameter("sort") != null && request.getParameter("sort").equalsIgnoreCase("time")){
				itemsList = Sort.byItemTime(itemsList);
			}
		} catch (Exception e) {
			addActionError("Problem retriving items.");
			return INPUT;
		}
		return SUCCESS;
	}


	public String confirmCancel(){
		try {
			if (request.getParameter("cancelId") != null) {
				String itemId = request.getParameter("cancelId");
				item = ItemsServiceDelegator.getItemsById(Integer.parseInt(itemId));
				date = DateUtil.getTodaysDate();
				user = SessionUtil.getUser(request);

			}
		} catch (Exception e) {

		}
		return SUCCESS;
	}
	public String cancelAuction(){
		try{
			if (request.getParameter("cancelId") != null) {
				String itemId = request.getParameter("cancelId");
				item = ItemsServiceDelegator.getItemsById(Integer.parseInt(itemId));
				BidStatus bidStatus;
				searchCriteria.removeAllAttribute();
				searchCriteria.setAttribute(AdminConstants.ID, 1);
				bidStatus = (BidStatus) (CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, BidStatus.class).size() > 0 ?CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, BidStatus.class).get(AdminConstants.ZERO_NUMBER) : new BidStatus());
				if(item.getItemtype().getId() == 1){
					List<AuctionBids> auctionBidsList = AuctionBidsServiceDelegator.getAuctionsBidsByitemId(Integer.parseInt(itemId));
					if(auctionBidsList != null && auctionBidsList.size() > 0){
						for (Iterator<AuctionBids> iterator = auctionBidsList.iterator(); iterator
								.hasNext();) {
							AuctionBids auctionBids = (AuctionBids) iterator
									.next();
							auctionBids.setBidStatus(bidStatus);
							CommonFunctionDelegator.generalUpdatebyobj(auctionBids);
						}
					}
				}
				item.setStatus(bidStatus);
				CommonFunctionDelegator.generalUpdatebyobj(item);
				myAccountCount = ((MyAccountCount) request.getSession().getAttribute(AttributeConstants.MYACCOUNTCOUNT));
				if(type.equals("auction")){
					if(myAccountCount.getSellingAuction() > 0){
						myAccountCount.setSellingAuction(myAccountCount.getSellingAuction() - 1);
					}
				}else if(type.equals("fixed")){
					if(myAccountCount.getSellingFixedPrice() > 0){
						myAccountCount.setSellingFixedPrice(myAccountCount.getSellingFixedPrice() - 1);
					}
				}else if(type.equals("shop")){
					if(myAccountCount.getSellingShops() > 0){
						myAccountCount.setSellingShops(myAccountCount.getSellingShops() - 1);
					}
				}
				request.getSession().setAttribute(AttributeConstants.MYACCOUNTCOUNT, myAccountCount);
				addActionMessage("Item cancelled successfully.");
				}else{
					addActionError("Error While retriving Item to cancel.");
					getSellingAuctionData();
					return INPUT;
			}
		}catch (Exception e) {
			logger.info(e.getMessage());
			getSellingAuctionData();
			addActionError("Error while cancel auctions item.");
			return INPUT;
		}
		return SUCCESS;
	}

	public void getSellingAuctionData(){
		try {
			user = SessionUtil.getUser(request);
			String auctionType = null;
			listingOptions = (ListingOptions) ActionContext.getContext().getApplication().get(AdminConstants.LISTING_OPTIONS);
			searchListCriteria.removeAllAttribute();
			searchListCriteria.setAttribute(AdminConstants.USERID ,new Object[]{user, SearchListCriteria.EQ});
			if(request.getParameter(AttributeConstants.T) == null){
				searchListCriteria.setAttribute(AttributeConstants.ITEMTYPE_ID,new Object[]{AttributeConstants.ITEMTYPE_STRAIGHTAUCTION, SearchListCriteria.EQ});
				auctionType = AttributeConstants.ITEMTYPE_STRAIGHT_AUCTION;
			}else if(!request.getParameter(AttributeConstants.T).equals(null)){
				auctionType = request.getParameter(AttributeConstants.T);
				if(auctionType.equalsIgnoreCase(AttributeConstants.ITEMTYPE_STRAIGHT_AUCTION)){
					searchListCriteria.setAttribute(AttributeConstants.ITEMTYPE_ID,new Object[]{AttributeConstants.ITEMTYPE_STRAIGHTAUCTION, SearchListCriteria.EQ});
				}else if(auctionType.equalsIgnoreCase(AttributeConstants.ITEMTYPE_FIXED_PRICE)){
					searchListCriteria.setAttribute(AttributeConstants.ITEMTYPE_ID,new Object[]{ AttributeConstants.ITEMTYPE_FIXEDPRICE, SearchListCriteria.EQ});
				}else if(auctionType.equalsIgnoreCase(AttributeConstants.ITEMTYPE_SHOP)){
					searchListCriteria.setAttribute(AttributeConstants.ITEMTYPE_ID,new Object[]{ AttributeConstants.ITEMTYPE_SHOPS, SearchListCriteria.EQ});
				}else{
					searchListCriteria.setAttribute(AttributeConstants.ITEMTYPE_ID,new Object[]{ AttributeConstants.ITEMTYPE_STRAIGHTAUCTION, SearchListCriteria.EQ});
				}
			}

			itemsListTemp = ItemsServiceDelegator.getListBySearchListCriteria(searchListCriteria);
			for (Iterator<Items> iterator = itemsListTemp.iterator(); iterator.hasNext();) {
				Items type = (Items) iterator.next();
//				if(type.getBids().size()>0)
				if(type.getStatus() != null && type.getEndTime() != null)
					if((type.getStatus().getId() == AdminConstants.ONE_NUMBER) ||(type.getStatus().getId() == 5) || (type.getEndTime().before(DateUtil.getTodaysDate())))
						continue;
				AuctionBids auctionBids = new AuctionBids();
				ItemNote itemNote = new ItemNote();
				searchListCriteria.removeAllAttribute();
				searchListCriteria.setAttribute(AttributeConstants.ITEMS, new Object[]{type, SearchListCriteria.EQ});
//				searchListCriteria.setAttribute(AttributeConstants.USER, new Object[]{user, SearchListCriteria.EQ});
				itemsWatchList = ItemsWatchListServiceDelegator.getList(searchListCriteria);
				type.setNoOfWatches(itemsWatchList.size());
				String[] giftIcon;
				giftIcon = type.getGiftIcon().split(AdminConstants.SEMICOLON);
				if(giftIcon.length > 0)
					type.setGiftIcon(giftIcon[0]);
				UserRating rating;
				if(!auctionType.equals(null)){
					if(auctionType.equalsIgnoreCase(AttributeConstants.ITEMTYPE_STRAIGHT_AUCTION)){
						if((type.getQuantity() != null) && (type.getSold() != null))
							type.setAvailable(type.getQuantity() - type.getSold());
							auctionBids = AuctionBidsServiceDelegator.getMaxBidder(type.getItemId());
							if(auctionBids != null){
								type.setBidder(auctionBids.getUser());
							}else{
								type.setBidder(new User());
							}
							searchCriteria.removeAllAttribute();
							searchCriteria.setAttribute("ratedUser.id", type.getBidder().getId());
							List<UserRating> ratingList = (List<UserRating>) CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, UserRating.class);
							rating = ratingList.size() > 0 ? ratingList.get(0) : null;
							if(rating != null){
								type.setUserRating(rating);
							}
					}
				}
				if(type.getEndTime().before(DateUtil.getTodaysDate())){
					type.setClosed(true);
				}else{
					type.setClosed(false);
				}

				if(type.getStartTime().before(DateUtil.addDate(type.getStartTime(), Calendar.DATE, listingOptions.getNumberOfDaysForNewListings()))){
					type.setNewIcon(true);
				}else{
					type.setNewIcon(false);
				}
				/* retrieving note */
				searchCriteria.removeAllAttribute();
				searchCriteria.setAttribute(AttributeConstants.ITEMS, type);
				searchCriteria.setAttribute(AttributeConstants.USER, user);
				itemNote = (ItemNote) ((CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, ItemNote.class)).size() > 0 ? CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, ItemNote.class).get(AdminConstants.ZERO_NUMBER) : new ItemNote());
				type.setItemNote(itemNote);
				ItemWantedBestOffer itemWantedBestOffer = new ItemWantedBestOffer();
				searchCriteria.removeAllAttribute();
				searchCriteria.setAttribute("itemId", type);
				itemWantedBestOffer = (ItemWantedBestOffer) ((CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, ItemWantedBestOffer.class)).size() > 0 ? CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, ItemWantedBestOffer.class).get(AdminConstants.ZERO_NUMBER) : null);
				if(itemWantedBestOffer != null){
					type.setItemWantedBestOffer(itemWantedBestOffer);
				}
				itemsList.add(type);
			}
		} catch (Exception e) {
			logger.error("Problem retriving items.");
		}
	}

	public String deleteItems() throws Exception{
		try {
			if(request.getParameter("action") != null){
				action = request.getParameter("action");
				if (request.getParameter("t") != null) {
					action = action.concat("?t="+request.getParameter("t"));
				}
			}
			ItemsServiceDelegator.deleteItems(request);
			addActionMessage("Items deleted successfully.");
			myAccountCount = ((MyAccountCount) request.getSession().getAttribute(AttributeConstants.MYACCOUNTCOUNT));
			if(myAccountCount.getSellingNotSold() > 0){
				myAccountCount.setSellingNotSold(myAccountCount.getSellingNotSold() - 1);
			}
			request.getSession().setAttribute(AttributeConstants.MYACCOUNTCOUNT, myAccountCount);
		} catch (Exception e) {
			logger.error(e.getMessage());
			addActionError("Error While deleting Items.");
			return INPUT;
		}finally{
			getNotSold();
		}

		return SUCCESS;
	}

	public String soldItems(){
		try{
			user = SessionUtil.getUser(request);
			listingOptions = (ListingOptions) ActionContext.getContext().getApplication().get(AdminConstants.LISTING_OPTIONS);
			if(itemsListTemp.size() > 0){
				itemsListTemp.clear();
			}
			if(itemsList.size() > 0){
				itemsList.clear();
			}
			itemsListTemp = ItemsServiceDelegator.getSoldItems(user);
			for (Iterator<Items> iterator = itemsListTemp.iterator(); iterator.hasNext();) {
				Items type = (Items) iterator.next();
				if(type.getBids().size()>0)
					if((type.getStatus().getId() == AdminConstants.ONE_NUMBER))
						continue;
				AuctionBids auctionBids = new AuctionBids();
				ItemNote itemNote = new ItemNote();
				searchListCriteria.removeAllAttribute();
				searchListCriteria.setAttribute(AttributeConstants.ITEMS, new Object[]{type, SearchListCriteria.EQ});
	//			searchListCriteria.setAttribute(AttributeConstants.USER, new Object[]{user, SearchListCriteria.EQ});
				itemsWatchList = ItemsWatchListServiceDelegator.getList(searchListCriteria);
				type.setNoOfWatches(itemsWatchList.size());
				String[] giftIcon;
				giftIcon = type.getGiftIcon().split(AdminConstants.SEMICOLON);
				if(giftIcon.length > 0)
					type.setGiftIcon(giftIcon[0]);
				if((type.getQuantity() != null) && (type.getSold() != null))
					type.setAvailable(type.getQuantity() - type.getSold());
				auctionBids = AuctionBidsServiceDelegator.getMaxBidder(type.getItemId());
				if(auctionBids != null){
					type.setBidder(auctionBids.getUser());
					type.setWinningBid(auctionBids);
				}else{
					type.setBidder(new User());
					type.setWinningBid(auctionBids);
				}
				if(type.getEndTime().before(DateUtil.getTodaysDate())){
					type.setClosed(true);
				}else{
					type.setClosed(false);
				}
				/* retrieving note */
				searchCriteria.removeAllAttribute();
				searchCriteria.setAttribute(AttributeConstants.ITEMS, type);
				searchCriteria.setAttribute(AttributeConstants.USER, user);
				itemNote = (ItemNote) ((CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, ItemNote.class)).size() > 0 ? CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, ItemNote.class).get(AdminConstants.ZERO_NUMBER) : new ItemNote());
				type.setItemNote(itemNote);
				itemsList.add(type);
			}
			if(request.getParameter("sort") != null && request.getParameter("sort").equalsIgnoreCase("title")){
				itemsList = Sort.byItemTitle(itemsList);
			}
			if(request.getParameter("sort") != null && request.getParameter("sort").equalsIgnoreCase("price")){
				itemsList = Sort.byItemBuyPrice(itemsList);
			}
			if(request.getParameter("sort") != null && request.getParameter("sort").equalsIgnoreCase("time")){
				itemsList = Sort.byItemTime(itemsList);
			}
		}catch (Exception e) {
			logger.error("Error in soldItems() method.");
			return INPUT;
		}

		return SUCCESS;
	}
	public String notSoldItems(){
		try {
			getNotSold();
		} catch (Exception e) {
			return INPUT;
		}
		return SUCCESS;
	}

	public void getNotSold(){
		user = SessionUtil.getUser(request);
		listingOptions = (ListingOptions) ActionContext.getContext().getApplication().get(AdminConstants.LISTING_OPTIONS);
		if(itemsListTemp.size() > 0){
			itemsListTemp.clear();
		}
		if(itemsList.size() > 0){
			itemsList.clear();
		}
		itemsListTemp = ItemsServiceDelegator.getNotSoldItems(user);
		for (Iterator<Items> iterator = itemsListTemp.iterator(); iterator.hasNext();) {
			Items type = (Items) iterator.next();
			if(type.getBids().size()>0)
				if((type.getStatus().getId() == AdminConstants.ONE_NUMBER))
					continue;
			ItemNote itemNote = new ItemNote();
			searchListCriteria.removeAllAttribute();
			searchListCriteria.setAttribute(AttributeConstants.ITEMS, new Object[]{type, SearchListCriteria.EQ});
//			searchListCriteria.setAttribute(AttributeConstants.USER, new Object[]{user, SearchListCriteria.EQ});
			itemsWatchList = ItemsWatchListServiceDelegator.getList(searchListCriteria);
			type.setNoOfWatches(itemsWatchList.size());
			String[] giftIcon;
			giftIcon = type.getGiftIcon().split(AdminConstants.SEMICOLON);
			if(giftIcon.length > 0)
				type.setGiftIcon(giftIcon[0]);
			if((type.getQuantity() != null) && (type.getSold() != null))
				type.setAvailable(type.getQuantity() - type.getSold());

			if(type.getEndTime().before(DateUtil.getTodaysDate())){
				type.setClosed(true);
			}else{
				type.setClosed(false);
			}
			/* retrieving note */
			searchCriteria.removeAllAttribute();
			searchCriteria.setAttribute(AttributeConstants.ITEMS, type);
			searchCriteria.setAttribute(AttributeConstants.USER, user);
			itemNote = (ItemNote) ((CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, ItemNote.class)).size() > 0 ? CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, ItemNote.class).get(AdminConstants.ZERO_NUMBER) : new ItemNote());
			type.setItemNote(itemNote);
			itemsList.add(type);
		}
	}
	public String sellFixedPrice(){
		return SUCCESS;
	}

	public static void main(String[] args) {
		int count = 0;
		User user = UserServiceDelegator.getUser(1);
		List<Criterion> criterionList = new ArrayList<Criterion>();
	    Itemtype itemType = (Itemtype) CommonFunctionDelegator.getObjectById(AdminConstants.ID, AttributeConstants.ITEMTYPE_STRAIGHTAUCTION, Itemtype.class);
		criterionList.add(Restrictions.eq(AdminConstants.USERID , user));
		criterionList.add(Restrictions.eq(AttributeConstants.ITEMTYPE, itemType));
		criterionList.add(Expression.or(Restrictions.ne("status", new BidStatus(5)), Restrictions.ne("status", new BidStatus(1))));
		criterionList.add(Restrictions.ge("endTime", DateUtil.getTodaysDate()));
	    count = CommonFunctionDelegator.getCountByCriterion(criterionList, Items.class);
	    System.out.println("Count :: " + count);
	}
	public List<Items> getItemsList() {
		return itemsList;
	}

	public void setItemsList(List<Items> itemsList) {
		this.itemsList = itemsList;
	}

	public List<ItemsWatchlist> getItemsWatchList() {
		return itemsWatchList;
	}

	public void setItemsWatchList(List<ItemsWatchlist> itemsWatchList) {
		this.itemsWatchList = itemsWatchList;
	}

	public List<AuctionBids> getAuctionBidsList() {
		return auctionBidsList;
	}

	public void setAuctionBidsList(List<AuctionBids> auctionBidsList) {
		this.auctionBidsList = auctionBidsList;
	}

	public void setServletRequest(HttpServletRequest arg0) {
		request = arg0;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public ListingOptions getListingOptions() {
		return listingOptions;
	}

	public void setListingOptions(ListingOptions listingOptions) {
		this.listingOptions = listingOptions;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public Items getItems() {
		return item;
	}

	public void setItems(Items items) {
		this.item = items;
	}

	public Items getItem() {
		return item;
	}

	public void setItem(Items item) {
		this.item = item;
	}

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

}
